package fr.ups.jim.isi.tp5 ;

import fr.lri.swingstates.canvas.CExtensionalTag;
import fr.lri.swingstates.canvas.CRectangle;
import fr.lri.swingstates.canvas.CStateMachine;
import fr.lri.swingstates.canvas.Canvas ;
import fr.lri.swingstates.canvas.CShape ;
import fr.lri.swingstates.canvas.CText ;
import fr.lri.swingstates.canvas.CStateMachine.EnterOnTag;
import fr.lri.swingstates.debug.StateMachineVisualization;
import fr.lri.swingstates.sm.State;
import fr.lri.swingstates.sm.Transition;
import fr.lri.swingstates.sm.transitions.Press;
import fr.lri.swingstates.sm.transitions.Release;
import fr.lri.swingstates.sm.transitions.TimeOut;

import javax.swing.JFrame ;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font ;

/**
 * @author Nicolas Roussel (roussel@lri.fr)
 *
 */
public class MySimpleButton {

    private CText label ;
    private CRectangle rect;
    private CStateMachine sm;
    private CExtensionalTag tag;

    private final int padding = 5;
    private final int[] borderWidth = {1, 2};
    private final Color[] color = {Color.WHITE, Color.YELLOW};
    
    MySimpleButton(Canvas canvas, String text) {
    	tag = new CExtensionalTag(canvas) {};
    	
    	label = canvas.newText(0, 0, text, new Font("verdana", Font.PLAIN, 20)) ;
    	label.setPickable(false);
    	rect = canvas.newRectangle(label.getMinX() - padding , 
    							label.getMinY() - padding,
    							label.getWidth() + 2*padding,
    							label.getHeight() + 2*padding);
    	rect.below(label).setParent(label);
    	rect.setStroke(new BasicStroke(borderWidth[0])).setFillPaint(color[0]);
    	rect.addTag(tag);
    	
    	
    	sm = new CStateMachine() {
    		
    		public State idle = new State() {
    			Transition toOver = new EnterOnTag(tag, ">> over");
    		};
    		
    		public State over = new State() {
    			public void enter() {
    				rect.setStroke(new BasicStroke(borderWidth[1]));
    			}
    			
    			Transition toIdle = new LeaveOnTag(tag, ">> idle");
    			Transition toArmed = new Press(">> armed");
    			
    			public void leave() {
    				rect.setStroke(new BasicStroke(borderWidth[0]));
    			}
    		};
    		
    		public State armed = new State() {
    			public void enter() {
    				rect.setStroke(new BasicStroke(borderWidth[1]));
    				rect.setFillPaint(color[1]);
    			}
    			
    			Transition toOver = new ReleaseOnTag(tag, ">> over") {
    				public void action() {
    					MySimpleButton.this.action();
    				}
    			};
    			Transition toDisarmed = new LeaveOnTag(tag, ">> disarmed");
    			
    			public void leave() {
    				rect.setFillPaint(color[0]);
    				rect.setStroke(new BasicStroke(borderWidth[0]));
    			}
    			
    		};
    		
    		public State disarmed = new State() {
    			public void enter() {
					   rect.setFillPaint(color[1]) ;
				}
				
    			Transition rearm = new EnterOnTag(tag, ">> armed") {} ;
				Transition cancel = new Release(">> idle") {} ;
			    
				public void leave() {
				   rect.setFillPaint(color[0]) ;
			    }
    		};
    		
    	};
    	
    	//sm.armTimer("tag", 20, true);
    	//TimeOut timeOut = new TimeOut(">> armed");
    	
    	sm.attachTo(canvas);
    }

    public void action() {
	   System.out.println("ACTION!") ;
    }

    public CShape getShape() {
	   return label ;
    }
    
    public void showStateMachine() {
    	JFrame vis = new JFrame();
    	vis.getContentPane().add(new StateMachineVisualization(sm));
    	vis.pack();
    	vis.setVisible(true);
    }

    static public void main(String[] args) {
	   JFrame frame = new JFrame() ;
	   Canvas canvas = new Canvas(400,400) ;
	   frame.getContentPane().add(canvas) ;
	   frame.pack() ;
	   frame.setVisible(true) ;

	   MySimpleButton simple = new MySimpleButton(canvas, "simple") ;
	   simple.getShape().translateBy(100,100) ;
	   simple.showStateMachine();
    }

}
